Skip to content

Cut three of seven CI jobs, and close the roster to growth without operator sign-off - #10390

Merged
briansrls merged 3 commits into
mainfrom
session/valiant-boar-411
Sep 4, 2026
Merged

briansrls merged 3 commits into
mainfrom
session/valiant-boar-411

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

The witnesses workflow carried seven jobs against a fleet that could not serve seven. The required context's wall is the MAX over its lanes, so jobs that gated nothing were displacing the ones that do, and the queue — not any lane's own cost — was what people waited on.

Deleted (2026-09-04 operator ruling)

job cost gated?
rust-unit-tests 60m cap yes — required lane
fabric-evidence ~27m every push/PR no
emit-copy-qualification-battery if: "false", never ran no

Remaining: required-witnesses-build, required-witnesses-floor, heal-generated-artifacts, and the witnesses aggregate. 7 → 4 jobs, and three release builds of one tree per PR instead of six. The required aggregate goes from three lanes to two.

Note what the third deletion does not buy: the battery was already skipped, so it consumed no runner time. It buys a roster that means what it says.

What was preserved

repo_self_clippy_command moved to required-witnesses-build as rust_clippy_all_targets_step, keeping its step id, its verdict and its required status. Deleting it would have been a below-floor regression under DESIGN §4b rather than a declared drop: it is the only command on any CI path that compiles the integration-test and example targets, which is how twelve of them sat red on main (2026-08-30) behind a green required run.

What was lost, declared

Five prose sites in emitted_closure_compile_seed_growth asserted this lane runs or gates. That clause has now been true → false → true in three weeks, so they are corrected to point at the authority rather than restate the shape a fourth time.

The roster is closed to growth

witness_floor_lane_jobs now carries what an author owes the operator before proposing a lane: a measured wall on a fleet runner, what its red discriminates, and why the check cannot be a step on a lane that already builds this tree.

That comment is rationale, not a gate, and says so. No Accepted program reads it. The construction that would make an over-budget roster unwritable is a runner-wall budget refused at emit time; it is not built, and pretending the comment is a wall would be exactly the decoration §4b warns about.

⚠️ Not verified locally

No regenerator could be reached from a session, so the generated artifacts in this commit are stale by construction and heal-generated-artifacts is expected to regenerate them:

  • BuildBuddy refuses gunbc run with HostBudgetUnreadable — no cgroup binds the runner, so entry_resolve will not plan against the machine's memory. Correct fail-closed behaviour, not a flake.
  • Locally, the only arm64 binary (/usr/local/bin/gunbc) cannot parse // comments. It fails identically on untouched HEAD — 4785 errors vs my tree's 4800, and the entire delta cascades from its own parse failure of rung_drop.dag:9.

This PR's first CI run is the first thing to parse these edits, and may well come back red on them. Reviewers should treat the .dag changes as unproven until it goes green.

That a session cannot exercise the regeneration path at all is a finding beyond this change, and probably wants its own issue — every generated artifact in the repo depends on it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Jc3hEtMTbDf2sdkaD2opDU

Brian Searls and others added 3 commits September 4, 2026 09:39
…erator sign-off (#10360)

The witnesses workflow carried seven jobs against a fleet that could not
serve seven. The required context's wall is the MAX over its lanes, so jobs
that gated nothing were displacing the ones that do, and the queue -- not
any lane's own cost -- was what people waited on.

Deleted, per the 2026-09-04 operator ruling:

  rust-unit-tests                  ~60m cap, required lane
  fabric-evidence                  ~27m every push/PR, gated nothing
  emit-copy-qualification-battery  if: "false", never ran

The build and floor lanes, the heal job and the aggregate remain: 7 -> 4
jobs, and three release builds of one tree per PR instead of six.

WHAT WAS PRESERVED, because deleting it would have been a below-floor
regression rather than a declared drop. `repo_self_clippy_command` moved to
`required-witnesses-build` as a step, keeping its step id, its verdict and
its required status. It is the only command on any CI path that compiles the
integration-test and example targets -- twelve of them sat red on main
(2026-08-30) behind a green required run.

WHAT WAS LOST, declared rather than left to be inferred from an absence:

  rung_drop rust_unit_tests_off_the_merge_path
      cargo test --release -p v1-compiler --lib now runs on no CI path.
      Trigger is runner supply, not a re-added job.

  rung_drop emit_copy_qualification_without_a_consumer
      the wet battery loses its only sanctioned consumer. Saves no runner
      time -- the job was already skipped -- and the row says so.

  rung_drop fabric_evidence_gating   AMENDED
      same lane, same trigger; temporary rung falls from mitigatable to
      outside the modeled guarantee, because there is no run left to read.

  rung_drop emitted_bytes_witness_required_lane   UN-RETIRED
      retired 2026-09-02 by #10078 BECAUSE rust-unit-tests became required.
      Deleting that job un-fires the trigger and its other arm was never
      built, so the class falls back below its declared rung. The original
      retirement adjudication is kept verbatim; only which fact stopped
      being true is added.

THE ROSTER IS NOW CLOSED TO GROWTH. `witness_floor_lane_jobs` carries what
an author owes the operator before proposing a lane: a measured wall on a
fleet runner, what its red discriminates, and why the check cannot be a step
on a lane that already builds this tree. That comment is rationale and not a
gate, and says so -- the construction that would make an over-budget roster
unwritable is a runner-wall budget refused at emit time, and it is unbuilt.

NOT VERIFIED LOCALLY, and this is the reason. No regenerator could be
reached from a session: BuildBuddy refuses `gunbc run` with
HostBudgetUnreadable (no cgroup binds the runner, so entry_resolve will not
plan against the machine's memory), and the only arm64 binary available,
/usr/local/bin/gunbc, cannot parse `//` comments -- it fails identically on
untouched HEAD, 4785 errors against my tree's 4800, the whole delta
cascading from its own parse failure. The generated artifacts in this commit
are therefore STALE BY CONSTRUCTION and heal-generated-artifacts is expected
to regenerate them. That a session cannot exercise the regeneration path at
all is a finding beyond this change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc3hEtMTbDf2sdkaD2opDU
…xpired paragraph

TWO FIXES, ONE PUSH, because the fleet is starved and a second run to
correct a comment would be self-refuting on a PR about runner scarcity.

THE RED. required-witnesses-floor refused the whole corpus:

  emit_copy_qualification_without_a_consumer.dag:15:235:
    error: field '_' not found in type 'AuthoredProse'

The prose carried BARE double quotes around `false` -- the string
terminated at column 235, `false` parsed as a field access, and the
declaration became unreadable. Every other rung_drop row escapes them as
\" and this one did not, because the heredoc that authored it consumed
the backslashes before they reached disk. Structural check, applied to
all four drop rows this branch touches: each now carries exactly 8
unescaped quotes -- identity, subject, declared and authored delimiters
-- matching the rows that already parse.

That was the ONLY corpus error in the run. modules_resolved=2467, and
nothing else in the branch failed to parse.

THE REVIEW REMARK (claude-opus-4-7, non-blocking). A 2026-09-03
measurement paragraph in emitted_closure_compile_seed_growth read as
current after my expiry note split it, leaving "three required lanes"
looking live. NOT fixed by s/three/two/, which was the suggestion: that
sentence is what the do-not-un-ignore verdict was decided on, there
genuinely were three lanes then, and the aggregate no longer waits on
that lane at any count. A number rewritten to match a later roster is no
longer the number anything was decided on. Fixed at the seam instead --
the old reasoning is fenced in its own tense, shifted to past, and says
plainly that there were three then and are two now.

STILL UNVERIFIED LOCALLY, for the reason the last commit gave: no
regenerator is reachable from a session. This fix is structural
reasoning against the rows that parse, not a compile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc3hEtMTbDf2sdkaD2opDU
…that can read the corpus

FIRST CLEAN COMPILE OF THIS BRANCH. `gunbc run ... generated_artifact_gate
main_wet` exits 0 with zero corpus errors, so every authority edit here --
the drop rows, the un-retirement, the witness rewrites, the DESIGN prose --
parses and typechecks. Until now nothing had read them.

WHAT REGENERATED, and it is the four projections the edits imply and
nothing else: .github/workflows/witnesses.yml, DESIGN.md,
docs/design-rung-drops.md, docs/design-failure-modes.md.

THE EMITTED WORKFLOW IS THE INTENDED SHAPE, verified from the artifact
rather than from the authority it came from:

  jobs:    required-witnesses-build, required-witnesses-floor,
           heal-generated-artifacts, witnesses        (7 -> 4)
  clippy:  "clippy, all targets" inside required-witnesses-build
  needs:   [required-witnesses-build, required-witnesses-floor]
  fabric_ci_evidence references: 0

That last line is what clears the `fabric-evidence` red: the stale workflow
was invoking a script this branch deleted, and the job and its script now
disappear together as they always should have.

HOW THE COMPILER WAS OBTAINED, STATED PLAINLY BECAUSE IT IS A WORKAROUND
AND NOT A REPAIR. This used another session's arm64 build under
/home/briansrls/.worktrees/neat-boar-641. The regeneration path itself is
still broken in both of its homes: BuildBuddy exposes no cgroup memory
limit so `gunbc run` refuses there with HostBudgetUnreadable, and the
session image's own /usr/local/bin/gunbc predates the DESIGN section 4c
annotation channel and cannot parse the `//` comments the corpus is full
of -- it fails identically on untouched main. Borrowing a peer's binary
is not a fix for either, and no row here claims it is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc3hEtMTbDf2sdkaD2opDU
@briansrls
briansrls merged commit 2094e9c into main Sep 4, 2026
@briansrls
briansrls deleted the session/valiant-boar-411 branch September 4, 2026 11:48
@briansrls
briansrls restored the session/valiant-boar-411 branch September 4, 2026 11:53
This was referenced Sep 4, 2026
briansrls pushed a commit that referenced this pull request Sep 4, 2026
* An annotation at scope end names nothing, and it has main red

main has been failing the required-ci parse phase since #10390 (11:48Z).
Every pull request that test-merges main fails required-witnesses-floor
with:

  required-ci: FAILED PHASE parse (16 error(s))
  required-ci: FAILED PHASE namespace-wave-admission (no head index)

All 16 are one file. #10390 deleted the three workflow-subject rows at the
end of test.claim.emit_copy_qualification_witness_test and left their
explanatory block behind as a TRAILING epilogue at lines 483-500, with no
module item after it. DESIGN section 4c admits only a leading block
attached to a module-scope declaration: an annotation names the
declaration that FOLLOWS it, so at scope end it names nothing.
AnnotationAttachmentRefusal::UnattachedAtScopeEnd is exactly that refusal,
and it fires once per line of the block.

The second failure is not independent. claim_executor pushes
"namespace-wave-admission (no head index)" only when the parse phase
produced no index, so the wave never ran at all. One root, two reported
blockers.

WHY THIS SURFACED LATE, since #10390 landed hours before anything went red
and a reader will otherwise suspect a different cause. The parse wall is
not new and #10325 only changed which receipt arm carries blockers. The
last green run on the old tree, #10358's 33869134455, was CREATED at 11:28
-- twenty minutes BEFORE #10390 merged -- so its merge ref predates the
breakage and it never parsed these lines. The first runs to test-merge the
broken main were the ones after it.

THE REPAIR MOVES THE BLOCK TO THE MODULE HEAD, where the imports that
follow give it a subject. Every sentence is preserved. The deictic words
are not: "stood here" becomes "stood at the END OF THIS MODULE", "the rows
above this comment" and "the mutants below" become "in this module",
because a relocated pointer that still says "below" is a false citation of
the kind this repository files as a_live_authority_name_carries_a_superseded_claim.
A trailing paragraph records why the block sits at the head, so the next
author does not move it back.

Nothing else changes: no row, no assertion, no rung drop. The content
already has a typed home at gunbc.rung_drop
emit_copy_qualification_without_a_consumer, and this commit does not touch
it.

EVIDENCE, executed on this tree rather than argued:

  before   required-ci: FAILED PHASE parse (16 error(s))
           required-ci: FAILED PHASE namespace-wave-admission (no head index)

  after    parse phase clean, no parse FAIL lines
           required-ci: namespace-wave-admission ADMITTED
                        -- every delta is auto-admitted or named by
                           a transition admission

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G

* The blank line was load-bearing: green parse, wrong subject

The previous head made the parse green and gave the annotation the WRONG
SUBJECT, which is worse than the refusal it replaced -- a plausible answer
standing where a typed refusal used to be is the failure DESIGN section 5
forbids outright, and I shipped it while claiming the fix was verified.

std.source_annotation module_header_gap_subject binds a post-module block
to the MODULE ROOT only when the block opens immediately after the module
line. Its first arm is

  if preceded_by_blank_line || preceded_by_annotation_line { none }

so a blank line between `module ...` and the first `//` deliberately
disables the module-root arm and sends the block through ordinary
nearest-following attachment. On the previous head that bound this
module-wide block to `import std.measure { byte_size }` -- an import it
never describes -- instead of to the module it describes throughout.

Removed that blank line. The blank line AFTER the block, before the
imports, is kept: it ends the block. Nothing else changed.

WHAT I HAD AND DID NOT USE. My evidence was "parse clean, wave ADMITTED".
Both were true and neither says anything about WHICH SUBJECT the annotation
acquired. A greener instrument reading is not evidence about the property I
was actually changing, and I generalized from it anyway.

EXECUTED: dag/test/claim/source_annotation_attachment_witness_test 13/13
PASS on this tree, and the parse phase reports zero parse FAIL lines.

COVERAGE GAP, NAMED NOT FIXED HERE. No enrolled witness covers
module_header_gap_subject's blank-line arm -- the exact rule that silently
mis-bound this block. The attachment battery covers general leading,
trailing, body-grain and block-splitting cases, but nothing discriminates
module-root attachment from nearest-following attachment across that one
bit. That witness belongs in its own change; this PR is a fleet unblocker
for a red main and is deliberately staying one file wide.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U397y4s3dSBof7vGPAX87G

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 4, 2026
…wer named it

Main was red at parse: #10390 left a trailing annotation block at EOF of
emit_copy_qualification_witness_test.dag with no declaration after it, 16 section 4c errors,
which took the head index down and with it the namespace-wave-admission verdict this branch
actually needs. Repaired on main; merged here. I filed nothing against it -- three PRs were
already open on that file.

The ledger entry for my own three verification bugs is rewritten in the reviewer's framing,
which is sharper than what I had. I wrote that an index which can be incomplete must be able
to say so. The precise statement is that A PARTIAL OBSERVER RETURNED THE NEGATIVE VALUE OF A
TOTAL OBSERVER.

That is the part that makes these dangerous rather than merely incomplete. A parser that
cannot see continuation-joined literals does not report that it failed to read a row -- it
returns the row set without it, the same type and shape a complete parser returns. An index
that does not know coproduct variants does not report that it lacks the form -- it returns
the empty owner set, which is exactly what a total index returns for a spelling nothing
declares. The answer is well formed and of the right type; only the meaning is wrong, and the
caller has no way to tell.

So the obligation sits on the observer, not the caller: anything reading the corpus that can
be partial must be able to say it was partial, or refuse. Three instances on this branch, one
shape -- an empty read from a transliterated path, a non-match from the import path, an empty
owner set from a pattern that did not cover the language.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9
briansrls pushed a commit that referenced this pull request Sep 4, 2026
…ect (#10428)

The floor lane refuses at `parse (16 error(s))` on every head since
2094e9c, so every open PR inherits a red it did not cause. All 16
are one file: the job-deletion note appended to
`test.claim.emit_copy_qualification_witness_test` sits AFTER the
module's last declaration, and DESIGN 4c admits an annotation only
attached to a module item. `std.source_annotation` refuses it as
`UnattachedAtScopeEnd` -- prose that names no subject.

The parser is right and the note is what moves.

Nothing is lost by moving it. The block's content -- the spent
activation token, the previous and temporary rungs, the bounded
population, the capability-grain restoration trigger -- is carried in
full, and in more detail, by the row it already cites,
`gunbc.rung_drop` `emit_copy_qualification_without_a_consumer`. So the
block was also a second authority for one fact. What it held that the
row does not is the warning to a reader OF THIS FILE, and that is kept
as a short pointer attached to the first module item, where 4c allows
it.

Executed evidence, one command
(`claim_executor --required-ci --required-lane witnesses`), one binary:

  main's version   parse FAIL x16, at 483:1..500:1, the exact lines CI reports
  this version     parse OK 4824 file(s) parse-clean

Two instruments answered this question wrongly before that pair was
run, and both looked green. `gunbc check` is not a subcommand -- it
printed usage, matched no error, and read as clean. `gunbc run` is a
real command that parses the broken file happily and executes it: the
`UnattachedAtScopeEnd` refusal belongs to the v2 parse phase, which the
v1 seed interpreter never applies. A one-sided green from either would
have shipped an unverified fix.


Claude-Session: https://claude.ai/code/session_019LhF5WCbZqrZHPqsnjpkYu

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 4, 2026
…carrying two contracts (#10355)

* Give the proposal vocabulary its own authority and stop one spelling carrying two contracts

gunbc.scm.merge answered a bounded question -- one target commit plus N authored
proposals, folded at role grain into one resulting root -- but it held the name
"merge". Two-commit merge is a materially different contract: two commit
occurrences and a derived common base, a different failure population, a
different output meaning. Section 3 says a materially different contract needs a
materially different name, and a second operation called merge was about to
arrive. This cuts the existing authority over BEFORE that happens rather than
after, because the fork is cheap to remove while it is still latent.

THE MODULE WAS ALSO THE ACCIDENTAL HOME OF ITS OWN INPUTS, and that was measured
rather than asserted. Of the eight modules importing gunbc.scm.merge, SIX
consumed only the proposal nouns and never the operation -- and three of those
six are production modules (gunbc.scm.status, gunbc.scm.authoring,
gunbc.scm.read_command). Only the two witness modules consumed the operation. A
vocabulary with three times the consumers of the operation it was filed under is
not a detail of that operation.

  gunbc.scm.proposal                      Requirement, RequireBinding,
                                          RequireBindingAbsent, requirement_role,
                                          Proposal, RoleDependency
  gunbc.scm.role_requirement_integration  everything else, with the outcome
                                          renamed off "Merge" through to the
                                          externally meaningful result

DesiredRoleValue STAYS WITH THE OPERATION, which corrects my own first partition.
I had placed it with the nouns on the reasoning that a contested alternative is
authored intent. The module's own annotation says otherwise and I had read past
it: a Requirement is authored syntax, a RoleValue is result provenance, and
DesiredRoleValue is the REQUESTED STATE that both normalize into -- produced by
normalize_requirement, which does object-store work and can refuse with a locator
collision. Derived from authored intent is not the same fact as authored intent;
a proposer cannot write one. Keeping it operation-side also keeps ObjectStore and
ObjectId out of the noun layer, so the dependency direction is proposal nouns ->
integration -> object store, never back.

RoleDependency, NOT ProposalDependency. The integration consumes this carrier in
TWO populations -- the target's own dependencies and the ones a proposal declares
-- and combines them in effective_dependencies, so a proposal-flavoured name
would make every target-side use a lie. It is named for the relation. Which
kinds an integration supports, which propagate a removal, and how an unsupported
kind refuses stay with the operation: that is classifier policy, not a property
of the row.

RESIDUE THIS DOES NOT CLOSE, recorded on the carrier rather than left silent:
target and target_dependencies still arrive as independent arguments and nothing
proves the second was derived from the first, so a foreign or empty population
can admit an invalid removal or fabricate a refusal. That is gunbc#10295's
subject-binding class at role-dependency grain. Moving the carrier to its right
home does NOT bind the population, and the annotation says so explicitly with a
next-rung trigger naming the capability.

PROSE MOVED WITH THE SYMBOLS. A rename that leaves notes pointing at the deleted
module is the evidence-bearing-narrative failure this lane was corrected on four
times: gunbc.scm.ancestry's mechanism citation, gunbc.scm.authoring's
apply_requirement citation, scm_authoring_witness_test's two references, the
signature block in dag-native-scm-design.md, and the current-state claim in
scm-demo-cli-rebuild.md. The witness module and its merge_-prefixed cells are
renamed too, so "merge" is free for the witness that will actually need it. The
terminal sweep over old identities leaves exactly one match, in the CLI plan,
and it is explicitly historical and invalidated.

No alias, no umbrella re-export: the old root is deleted, so a future import
cannot keep choosing the ambiguous authority.

EVIDENCE. Semantically a no-op, which is the whole claim: 83 cells across the
five affected witness modules pass, zero fail, and all nine touched modules
resolve and typecheck. Ancestry is untouched semantically -- MergedFrom and the
commit-merge model are the second cut and wait on the ancestry result shape being
settled first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

* Rename the witness module identity too, which my own sweep pattern could not see

REQUEST_CHANGES on #10355 (review 59814). Correct, and it exposes a hole in the
verification I ran rather than only a missed line.

The file was renamed and the operation was renamed, but the module DECLARATION
still read:

  module test.claim.scm_merge_witness

so the witness authority kept the exact spelling this PR exists to free, against
the contract it no longer describes.

WHY MY SWEEP MISSED IT, which is the part worth recording. The terminal sweep ran
over `scm_merge_witness_test` -- the FILE stem. The module identity is
`scm_merge_witness`, with no `_test` suffix, because the corpus convention is
`test.claim.scm_<name>_witness` for a file named `scm_<name>_witness_test.dag`.
The pattern was strictly narrower than its subject, so it reported clean over a
tree that still contained five matches. A green instrument that cannot express
the defect is the decoration DESIGN section 4b calls worse than absent, and this
is the same class the SCM reviewer warned about one round earlier: a stale
identity survives a sweep keyed to the wrong spelling.

The corrected pattern drops the suffix, and it is the one in this commit's
verification: `scm_merge_witness` matches both forms, `scm_merge_witness_test`
matches only one.

FOUR MORE REFERENCES were behind that hole -- the finding named one:
  the module declaration itself
  scm_commit_closure_json_v2_witness_test's annotation about where the merge-arm
    claim lives, which additionally cited it WRONG as `test.claim.scm.scm_merge_witness`
    with a segment that never existed
  three citations in docs/plans/dag-native-scm-design.md, all naming the claim
    population that measures kernel coverage

Renamed to `test.claim.scm_role_requirement_integration_witness`, matching the
convention its 24 siblings use.

The corrected sweep now leaves three matches, all in the same commit's own prose,
all unmistakably historical and explicitly invalidated: "previously lived in",
"It was `MergeDependency`", "formerly `gunbc.scm.merge`".

62 cells pass across the two touched witness modules, zero fail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

* Retire the last merge tags, fix a citation that was wrong before I touched it, and withdraw "semantic no-op"

Three findings on this head. All correct.

1. FOUR LIVE MERGE TAGS SURVIVED the rename because they are not identities my
sweep pattern covers -- they are helper and tag functions, not module or type
names: outcome_is_merged, merged_roles, scm_image_merge_refusal_tag,
scm_image_merge_tag_for. Renamed to the integration vocabulary. The two witness
modules now contain no function whose name carries "merge".

2. A CITATION I REWROTE POINTED AT A SYMBOL THAT HAS NEVER EXISTED. The authoring
witness said its node helper was "built exactly as ... `atom_node`". No atom_node
has ever existed in the cited module -- it lives in
test.claim.scm_object_store_witness. The citation was ALREADY WRONG on main; what
this change did was rewrite its MODULE half while carrying the stale SYMBOL half
forward, which makes an unverified name look freshly checked. That is worse than
leaving it alone, because a rewritten citation reads as re-derived.

Both halves are now derived rather than copied: the symbol is
integration_witness_leaf, and the annotation states what makes the claim true --
the two bodies are byte-identical node_synthetic over an Atom connective. The
error's history is recorded because a future reader has no other way to know the
citation was stale rather than broken by this rename.

3. "SEMANTICALLY A NO-OP" WAS TOO STRONG AND I AM WITHDRAWING IT. Two different
facts were riding on one sentence:

  PRODUCTION BEHAVIOUR is unchanged. Every moved declaration is byte-identical
  modulo its name; no fold, arm, refusal or classifier changed. That part was
  true.

  THE CLAIM CORPUS IS NOT UNCHANGED. Five claim identities were renamed -- four
  in the integration witness and one in the JSON codec witness -- along with the
  module identity and six helpers. At identity grain a renamed claim is a
  deletion plus an addition, not the same claim, which is exactly the standard
  this lane applies to residues and rosters. Calling that a no-op used the
  passing count as evidence for a claim the count cannot support.

WHAT MAKES THE RENAMES SAFE IS A DIFFERENT CHECK, and it is the one that was
missing: every renamed identity was grepped across .dag, .md, .rs and .yml for a
citation outside its defining file. There are none, so no roster, coverage table
or coverage number is invalidated. The design doc's kernel coverage table names
claims -- an_independent_sibling_is_preserved_exactly,
two_distinct_requests_for_one_role_are_contested, dependent_add_and_delete_refuses,
the_same_request_authored_twice_is_not_a_contest -- and none of them is renamed
here, checked one at a time rather than by pattern.

67 cells pass across the three touched witness modules, zero fail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

* Derive the whole claim-identity population, not the four names I happened to rename

The reviewer's point is structural: renaming a module re-qualifies EVERY claim it
declares. The four renamed locals were a subset of the migration, and reporting them
as the migration understated it by fifteen. The complete population is 20 identities
-- all 19 in the renamed module (4 of which also change local name), plus one pure
local rename in scm_commit_closure_json_v2_witness, whose module identity is unchanged.

Checked against that population rather than against the four: five of the nineteen are
cited in the SCM design document, none of them among the renamed four, and no workflow
YAML, roster or coverage join enrolls the module by name -- so the re-qualification has
no enrollment consequence to migrate. `git grep scm_merge_witness` is empty.

While checking the coverage join I found a transcribed count that had rotted: the design
document said "the 15 claims in test.claim.<module>" while the module declares 19. It was
true when #8794 wrote it and has been wrong since. Per DESIGN section 6 the fix is not a
corrected number -- both sites now name the module and let the count be re-derived.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

* Close the meaning fork where it actually lived, and pay the roster's sweep

Three things, all from review 5110471067 plus the required gate.

THE DESIGN DOCUMENT STILL DEFINED merge AS PROPOSAL-COMBINATION. I renamed the modules and
swept their prose, then wrote a vocabulary row saying the operation is no longer called
merge -- while the document below that row still carried "## 4. What merge is", "merge
kernel", "Structural merge", "depth changes how merge combines" and "Merges are not always
safe", all present tense. A new definition sitting above the old one does not replace it;
that is the same fork inside one artifact, and it was the fork I claimed to have closed.
Migrated at the root: proposal-combination is role-requirement integration throughout,
merge is now reserved for the two-commit operation, and section 4 says so in its own body.
Thirteen surviving uses are line-based merge, git's merge-as-invoked-event, the two-commit
contrast, or explicitly historical.

THE COMMON-ANCESTOR REFUSAL WAS MATHEMATICALLY WRONG AND IS WITHDRAWN. The refused-concepts
table said merge base / common ancestor "requires a total order that need not exist". A
commit DAG supplies a PARTIAL ancestry order; common ancestors are the intersection of two
ancestor closures and best common ancestors are the maximal elements of that intersection.
No total order is involved. Withdrawn in place rather than deleted, because it is a
prerequisite of the two-commit merge design this note does not yet model.

THE CENSUS HAD THE RIGHT ARITHMETIC AND THE WRONG UNIT. "20 claim identities" conflates
migrations with identity values: each transition removes one and adds one, so the symmetric
difference holds 40. It is 20 claim-identity MIGRATIONS. The population is unchanged.

NAMESPACE-WAVE-ADMISSION. The required run refused with 30 unadjudicated deltas -- exactly
my 30 binding sites retargeted from gunbc.scm.merge to gunbc.scm.proposal. Rows added.
Touching the roster sets roster_touched, which makes its 142 consumed rows due for deletion
on this change, so they are swept. Their consumption was READ FROM THE BASE rather than
taken from the run that reported it: for all 142, the row's own module imports the row's
spelling from extdeps.systems.nvidia_dgx_spark_setup by name. That check is what the
roster's own comment says costs a required run whenever it is guessed instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

* A withdrawn row cannot sit inside the population it left, and a dated join cannot cite a renamed module

Two authority defects from review 5110979857, both of them mine and both introduced by
fixes rather than found under them.

THE WITHDRAWN ROW WAS STILL A MEMBER OF THE REFUSED SET. I marked "merge base / common
ancestor" as withdrawn but left it inside a table introduced by "Terms deliberately refused
-- every one", under a column literally named `refused`. The row and its container then
asserted opposite things about the same term, which is the fork I had just spent the branch
closing, reproduced one level up in the containing structure. The table is now a disposition
table: each term's standing is stated by its own cell, and membership no longer asserts
refusal.

A DATED MEASUREMENT CANNOT CITE A MODULE THAT HAS SINCE BEEN RENAMED. Removing the stale
"15" was right for the "witnesses are not consumers" sentence, which needs no cardinality. I
applied the same edit to the 2026-08-21 coverage join, and that sentence is a different
subject: it now claimed 4 of 13 came from joining "every claim declared in
test.claim.scm_role_requirement_integration_witness", a module identity and population that
did not exist on 2026-08-21. Naming a changing module does not re-run a historical join --
it makes a dated receipt look re-derived when nothing re-derived it, which is worse than the
stale number I replaced. Historicized: the figure is stated as the result of the join over
the population that existed that day, with no current-completeness claim, and the missing
current-head instrument is named as what would be needed to restate it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

* Take main's parse repair, and name my own bug class the way the reviewer named it

Main was red at parse: #10390 left a trailing annotation block at EOF of
emit_copy_qualification_witness_test.dag with no declaration after it, 16 section 4c errors,
which took the head index down and with it the namespace-wave-admission verdict this branch
actually needs. Repaired on main; merged here. I filed nothing against it -- three PRs were
already open on that file.

The ledger entry for my own three verification bugs is rewritten in the reviewer's framing,
which is sharper than what I had. I wrote that an index which can be incomplete must be able
to say so. The precise statement is that A PARTIAL OBSERVER RETURNED THE NEGATIVE VALUE OF A
TOTAL OBSERVER.

That is the part that makes these dangerous rather than merely incomplete. A parser that
cannot see continuation-joined literals does not report that it failed to read a row -- it
returns the row set without it, the same type and shape a complete parser returns. An index
that does not know coproduct variants does not report that it lacks the form -- it returns
the empty owner set, which is exactly what a total index returns for a spelling nothing
declares. The answer is well formed and of the right type; only the meaning is wrong, and the
caller has no way to tell.

So the obligation sits on the observer, not the caller: anything reading the corpus that can
be partial must be able to say it was partial, or refuse. Three instances on this branch, one
shape -- an empty read from a transliterated path, a non-match from the import path, an empty
owner set from a pattern that did not cover the language.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ4iThiZ1B9LPB9ePr8qa9

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 4, 2026
#10425, #10408 and #10428 each deleted the 19-line annotation #10390 orphaned at EOF and
each added its own relocation. Every repair was correct alone; landing together they left
the same paragraph in the module three times, and no check can see it because all three
parse.

Copy C also inverted its own claim -- "no row in this module establishes nothing about a
running system" -- a double negative asserting the opposite of the intended sentence.

Keeps the module-head copy, which is the only one whose deictics were rewritten to name
the module rather than point at "here"/"below", the only one with correct polarity, and
which already carries the relocation account the others state separately. Deletes the
other two and the blank line that would otherwise double up.

Declaration set identical; the only non-comment change is that blank. Parsed both arms
with the local gunbc against main's own copy as control -- both parse, both return true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PGkDt1W1m3U28vBpV6BY9Z
gunbai-bot Bot pushed a commit that referenced this pull request Sep 4, 2026
…e module emit-core hosts can reach the authority it asks

Main parses again at 159421d (#10428 re-attached the annotation #10390 orphaned),
so this is the one integrate-main push, carrying the build repair with it.

THE BUILD FAILURE THIS FIXES, AT ITS ROOT RATHER THAN AT ITS SYMPTOM.
v1_compiler_emit_core_support is compiled TWICE from one file: once inside
v1-compiler, where crate::v1_compiler_parse resolves, and once inside
v1-stage0-emit-core via #[path], where the crate root offered eight modules and
parse was not one of them. Its reachable set is the INTERSECTION of two crate
roots, so consuming the parser's single authority for "is this item a resource"
compiled in one and E0432/E0433'd in the other.

The emit-core crate's own generated doc says it exists to host that module
"without copying semantics". The missing name was defeating that: the
alternatives were to FORK the predicate into a module that cannot see the
minting vocabulary it is defined against, or to SCATTER the exclusion across the
call sites. So the boundary was the defect, not the predicate, and the fix is to
make the root set true rather than to work around it.

WHY NOT THE OTHER ARMS, since a reviewer meeting a partition edit inside a
namespace-cut PR should not have to reconstruct this.

  MOVE the predicate down beside Node. Rejected: it is defined NEGATIVELY over
  parse's minting vocabulary -- true if any property's name is not
  "sole_constructor" -- so it is a statement ABOUT that vocabulary, and
  v1.compiler.parse's own note scopes it "complete against the parser's minting
  vocabulary AS OF THIS COMMIT". A definition whose truth is maintained by a
  module it cannot see is a fork with a delay on it.

  APPLY THE EXCLUSION IN THE CALLERS. Rejected on its own measurement. The
  hypothesis was four call sites; the enumeration is 24 call expressions in 12
  functions across v1.compiler.emit_rust (19/9), emit_go, emit_python,
  trait_derive_emit, plus the census reader. Twelve hand-applied exclusions is
  twelve places the next property-minting modifier reintroduces the defect with
  nothing watching -- verbatim the failure parse's note predicts.

WHAT LANDS. v1_compiler_parse joins the v1-infer unit and std_import joins
std-core, chosen for LAYER: parse is a pipeline stage and sits beside
v1_compiler_coercion and the infer modules. parse is a SOURCE in that unit --
nothing there is reachable from it -- so the unit graph gains no edge back, and
validate_partition_r4 adjudicates that mechanically via SccSplit/UnitGraphCycle
rather than by this paragraph. Every generated artifact in the chain was
regenerated through its authority: the roster by the generated-artifact gate,
the stage0 mirrors by --required-regen, the crate manifests and lib roots by
--emit-partition-crates. No hand-edited generated bytes.

THE TRANSITIVE CLOSURE IS THE CHECK, NOT THE IMMEDIATE DEPENDENCIES. An earlier
report of this change said parse depends on eight modules and std_import on two.
That is the immediate set and it passes cleanly on a closure that fails two
levels down. The transitive closure of both seeds is 29 modules; 27 are already
partitioned and the 2 remaining are the seeds themselves, so nothing else is
dragged in -- corroborated independently by the emitter, which drifted three lib
roots and NO Cargo manifest, meaning no new inter-crate dependency was required.

THE ADMISSION ENTRY WAS RE-APPLIED ACROSS THIS MERGE, NOT CARRIED. The
conflicting hunk was a misaligned array head -- this cohort's label line against
the SCM cohort's, with the body below the marker belonging to the other subject
-- so resolving the markers in place would have spliced one cohort's rows onto
another's body. Main's file was taken whole and the delta re-derived at ROW
IDENTITY grain against the merge base: 2 added here, 0 removed, against main's
29 additions and 254 removals. Merged array is 32 rows, no row of either side
dark. The entry is renumbered TWENTY-THIRD and its citation of the
now-dissolved twenty-sixth entry repointed, because #10355 deleted the entry it
named.

Verified by execution on the merged tree, not by inspection: cargo build green
with the repair present and reached, cargo clippy --all-targets -D warnings
clean, and compiler_tests::a_resource_item_is_not_read_as_a_type_item passing
with its positive control, resource discriminator, sole_constructor
over-correction guard and two-reader agreement assertion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg
gunbai-bot Bot pushed a commit that referenced this pull request Sep 4, 2026
… the infer mirror from the merged authority

Second integrate-main cycle on this branch. #10350 was CONFLICTING, which is
not merely a merge chore: GitHub cannot compose refs/pull/N/merge for a
conflicting PR, so no pull_request event is built and ZERO runs are created --
measured, total_count=0 for head 5250ea6. The stale composed tree GitHub kept
serving (still carrying #10390's orphaned annotation, long after #10425 repaired
it on main) is a SYMPTOM of the same missing ref, not a second defect. Both end
here.

dag/gunbc/recurring_failure_mode/roster.dag -- UNION, and union is correct here
for a reason worth stating, because the same resolution authored a real defect on
main tonight. This roster is an append-only SET whose entries are independent
rows, so keeping both sides preserves two unrelated appends. The duplicate
annotation preambles now sitting in main came from union-resolving a PROSE BLOCK,
where "keep both sides" mints a second authority for one statement. Same
resolution, opposite correctness, and what decides it is whether the file is a
set or a narrative. Verified at row identity rather than by count: HEAD 102 rows,
main 105, merged 107 = exactly the union, zero dark from either side, zero
invented, and every roster entry has a matching import.

src/v1/stage0/src/v1_compiler_infer.rs -- NOT hand-resolved. It is a generated
mirror and #10402 landed on it while this branch moved
resolved_node_is_kernel_identity_for_name out of the infer_env import block. The
authority src/v1/04_infer.dag auto-merged clean, so the mirror was taken
base-side and RE-DERIVED from the merged authority by --required-regen
(planned=156 executed=156 adjudicated=156, drift reported on exactly lib.rs and
this file). The check that a hand merge cannot pass: the derived mirror DIFFERS
FROM BOTH PARENTS -- 87 changed lines against this branch, 59 against main. Had
either side's delta been dropped it would have come out identical to one of them.

dag/test/claim/emit_copy_qualification_witness_test.dag needed no resolution and
got none: this branch has no changes to it, and the merged worktree copy is
byte-identical to main's 565-line repaired file.

Verified on the merged tree: cargo clippy --all-targets -- -D warnings clean, and
compiler_tests::a_resource_item_is_not_read_as_a_type_item green against a test
binary built AFTER the mirror was re-derived (checked by mtime, since an
unchanged cargo metadata hash does not mean an unchanged binary).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018vz8ESEVFC7Cox1xAaXudg
gunbai-bot Bot added a commit that referenced this pull request Sep 4, 2026
…deictics that no gate can see (#10434)

`dag/test/claim/emit_copy_qualification_witness_test.dag` on main holds THREE copies of the
same block, at lines 2, 74 and 99. Only the first is #10425's repair. The other two are the
PRE-REPAIR text, and their deictics are now false at their positions:

    "Three rows stood HERE ..."          the rows were deleted by #10390
    "calibration mutants BELOW ..."      points at rows that are not below it
    "the rows ABOVE THIS COMMENT ..."    points at rows that do not exist

#10425 rewrote exactly those words for exactly this reason, recording that "a relocated
pointer that still says below is a false citation of exactly the kind this repository files."
Two stale copies then landed beside its corrected one.

HOW IT ARRIVED, and it is not #10425's fault. Two PRs cut BEFORE the repair (#10408, #10376)
carried their own copy of the block and landed after it. Neither contested a line, so the
merge UNIONED rather than refused and both sides' bytes survived. This is
`gunbc.recurring_failure_mode` `append_only_carrier_whose_serialization_shares_a_merge_region`
on ordinary source rather than on a roster: THE UNIT OF MERGE IS COARSER THAN THE UNIT OF EDIT.

WHY NOTHING CAUGHT IT. All three copies are leading blocks attached to declarations, so §4c is
satisfied and the parse phase is silent. The defect we spent the afternoon on announced itself
in 16 errors; this one is the same class, from the same commit family, and is invisible to
every gate we have. A green main is not evidence this did not happen.

This deletes copies B (74-91) and C (99-116) and keeps A at the module head — the one whose
deictics name the module. Result: one copy, zero false deictics, no unattached block, and the
file still ends at its last declaration.


Claude-Session: https://claude.ai/code/session_01LSzWg5t7F22xEtbd83fzQ6

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 4, 2026
…trument consumes

Four conflicted paths and one silent deletion, resolved three different ways.

THE TWO SCRIPTS ARE RESTORED UNDER A RULING. #10390 deleted tools/fabric_ci_evidence_driver.sh and
tools/fabric_ci_evidence_calibration.sh as passengers of the fabric-evidence CI job, per the
2026-09-04 operator ruling on runner capacity. This branch carries their only remaining consumers:
tools/fabric_ci_fci1_live_instrument.sh sources the driver for fabric_ci_driver_init,
fabric_ci_run_assertion (24 call sites) and fabric_ci_capture_transport, and calls the calibration
before any srv3 observation because, as the instrument states, FCI-1 cannot self-grade the evidence
boundary -- which is what gunbc.fabric_ci_program FCI-1 positive_control opens on.

The ruling's subject is RUNNER CAPACITY. Both consumers are operator-invoked on srv3 and cost no CI
wall, so restoring the files does not touch the quantity the ruling governs; it restores collateral
the ruling did not weigh. Nothing the operator decided is undone. The enforcing witness
test.claim.witness_floor_workflow_consolidation_witness_test w_RED_the_deleted_lanes_do_not_return
matches on expected_witness_floor_yml() and nothing else, and its calibration clause matches the
ARGV STRING rather than a path, so a restored file with no argv leaves all five clauses true --
verified in the regenerated workflow, where the fabric-evidence job header, the FABRIC_EVIDENCE
binding and the calibration argv are all absent.

THE DRIVER'S DELETION RAISED NO CONFLICT, TWICE, AND THAT IS THE PART WORTH RECORDING. Git conflicts
on paths the branch EDITED. A dependency merely CONSUMED is invisible to that mechanism, so an
upstream deletion of a file this branch sources arrives as a clean merge and fails at runtime. The
calibration script conflicted only because its dissolution trigger had been repaired hours earlier;
the driver -- the harder dependency, since the instrument cannot initialise without it -- vanished
silently on both merge attempts for exactly the reason that it was working and needed no changes.
The conflict set is not the dependency set, and the files at greatest risk are the ones there is
least reason to touch.

THE THREE GENERATED PATHS WERE RE-DERIVED, NEVER HAND-RESOLVED. .gitattributes and
.github/workflows/witnesses.yml come from gunbc.generated_artifact_gate main_wet. src/v1/stage0/src/
std_measure.rs and compiler_tests.rs are seed mirrors installed from the candidate tree, which is
emitted from dag/std/measure.dag -- an authority that merged cleanly and carries both sides. The
first regen pass reported drift in both mirrors because the binary had been built while
std_measure.rs was still unmerged and carrying the ours side verbatim, which is the driver's
documented refusal shape rather than a real divergence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015nNrB6jSEPS99LPx8zcvqk
briansrls pushed a commit that referenced this pull request Sep 5, 2026
…ect (#10433)

The floor lane refuses at `parse (16 error(s))` on every head since
2094e9c, so every open PR inherits a red it did not cause. All 16
are one file: the job-deletion note appended to
`test.claim.emit_copy_qualification_witness_test` sits AFTER the
module's last declaration, and DESIGN 4c admits an annotation only
attached to a module item. `std.source_annotation` refuses it as
`UnattachedAtScopeEnd` -- prose that names no subject.

The parser is right and the note is what moves.

Nothing is lost by moving it. The block's content -- the spent
activation token, the previous and temporary rungs, the bounded
population, the capability-grain restoration trigger -- is carried in
full, and in more detail, by the row it already cites,
`gunbc.rung_drop` `emit_copy_qualification_without_a_consumer`. So the
block was also a second authority for one fact. What it held that the
row does not is the warning to a reader OF THIS FILE, and that is kept
as a short pointer attached to the first module item, where 4c allows
it.

Executed evidence, one command
(`claim_executor --required-ci --required-lane witnesses`), one binary:

  main's version   parse FAIL x16, at 483:1..500:1, the exact lines CI reports
  this version     parse OK 4824 file(s) parse-clean

Two instruments answered this question wrongly before that pair was
run, and both looked green. `gunbc check` is not a subcommand -- it
printed usage, matched no error, and read as clean. `gunbc run` is a
real command that parses the broken file happily and executes it: the
`UnattachedAtScopeEnd` refusal belongs to the v2 parse phase, which the
v1 seed interpreter never applies. A one-sided green from either would
have shipped an unverified fix.


Claude-Session: https://claude.ai/code/session_019LhF5WCbZqrZHPqsnjpkYu

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant